#!/usr/bin/env python3
"""
lua-lunit MCP Server

面向 lua-lunit 单元测试框架的 MCP 服务器，提供对 lunit 命令行工具的封装。

MCP tools 列表：
- lunit_version: 获取 lunit 版本信息
- lunit_path: 设置 Lua 模块搜索路径并运行测试
- lunit_interpreter: 指定 Lua 解释器运行测试
- lunit_cpath: 设置 C 模块搜索路径并运行测试
- lunit_runner: 指定测试运行器运行测试文件
- lunit_test: 运行指定的测试文件
- lunit_loadonly: 仅加载测试文件而不运行
- lunit_dontforce: 不强制执行测试
- lunit_help: 显示 lunit 帮助信息

所有工具返回统一的 JSON 结构：
{
  "success": bool,
  "command": str,
  "exit_code": int,
  "stdout": str,
  "stderr": str
}
"""

import subprocess
import shlex
from typing import List, Optional
from mcp.server.fastmcp import FastMCP, Context

mcp = FastMCP("Lua-Lunit MCP Server")

@mcp.tool()
def lunit_version() -> dict:
    """
    获取 lunit 版本信息
    
    返回:
        dict: 包含命令执行结果的统一 JSON 结构
    """
    command = "lunit --version"
    try:
        result = subprocess.run(shlex.split(command), capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def lunit_path(path: str) -> dict:
    """
    设置 Lua 模块搜索路径并运行测试
    
    参数:
        path: Lua 模块搜索路径，格式如 "/usr/share/lua/5.4/?.lua;?.lua"
    
    返回:
        dict: 包含命令执行结果的统一 JSON 结构
    """
    command = f"lunit --path {shlex.quote(path)}"
    try:
        result = subprocess.run(shlex.split(command), capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def lunit_interpreter(interpreter: str) -> dict:
    """
    指定 Lua 解释器运行测试
    
    参数:
        interpreter: Lua 解释器名称，如 "lua"
    
    返回:
        dict: 包含命令执行结果的统一 JSON 结构
    """
    command = f"lunit --interpreter {shlex.quote(interpreter)}"
    try:
        result = subprocess.run(shlex.split(command), capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def lunit_cpath(cpath: str) -> dict:
    """
    设置 C 模块搜索路径并运行测试
    
    参数:
        cpath: C 模块搜索路径，格式如 "./?.so"
    
    返回:
        dict: 包含命令执行结果的统一 JSON 结构
    """
    command = f"lunit --cpath {shlex.quote(cpath)}"
    try:
        result = subprocess.run(shlex.split(command), capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def lunit_runner(runner: str, test_file: str) -> dict:
    """
    指定测试运行器运行测试文件
    
    参数:
        runner: 测试运行器名称，如 "lunit"
        test_file: 测试文件路径
    
    返回:
        dict: 包含命令执行结果的统一 JSON 结构
    """
    command = f"lunit --runner {shlex.quote(runner)} {shlex.quote(test_file)}"
    try:
        result = subprocess.run(shlex.split(command), capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def lunit_test(test_files: List[str]) -> dict:
    """
    运行指定的测试文件
    
    参数:
        test_files: 测试文件路径列表
    
    返回:
        dict: 包含命令执行结果的统一 JSON 结构
    """
    files_str = " ".join(shlex.quote(f) for f in test_files)
    command = f"lunit --test {files_str}"
    try:
        result = subprocess.run(shlex.split(command), capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def lunit_loadonly(test_file: str) -> dict:
    """
    仅加载测试文件而不运行
    
    参数:
        test_file: 测试文件路径
    
    返回:
        dict: 包含命令执行结果的统一 JSON 结构
    """
    command = f"lunit --loadonly {shlex.quote(test_file)}"
    try:
        result = subprocess.run(shlex.split(command), capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def lunit_dontforce(test_file: str) -> dict:
    """
    不强制执行测试
    
    参数:
        test_file: 测试文件路径
    
    返回:
        dict: 包含命令执行结果的统一 JSON 结构
    """
    command = f"lunit --dontforce {shlex.quote(test_file)}"
    try:
        result = subprocess.run(shlex.split(command), capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def lunit_help() -> dict:
    """
    显示 lunit 帮助信息
    
    返回:
        dict: 包含命令执行结果的统一 JSON 结构
    """
    command = "lunit --help"
    try:
        result = subprocess.run(shlex.split(command), capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

if __name__ == "__main__":
    mcp.run()